package optional;

import lambda.User;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * Optional类常用方法使用示例
 * 使用场景：解决实际业务中多个值判空问题
 *
 * @author <a href="mailto:sjj@jianzhimao.com">mojo</a>
 * copyright (C), 2013-2022, 广州九尾信息科技有限公司
 * @date 2022/3/22 15:37
 */
public class OptionalDemo1 {
    public static void main(String[] args) {
        //of方法,静态方法返回Optional实例
        User user = new User("jj");
        User u = null;
        Optional<User> op1 = Optional.of(user);
        //ofNullable方法，判空并返回optional实例，本质调用empty方法
        Optional<User> op2 = Optional.ofNullable(u);
        //ifPresent,存在则调用Consumer
        op1.ifPresent(t -> System.out.println("user1名称长度" + t.getName().length()));
        op2.ifPresent(t -> System.out.println("user2名称长度" + t.getName().length()));
        User user3 = op1.orElse(u);
        //orElseGet,无元素则通过Supplier返回新的元素
        System.out.println(op2.orElseGet(() -> new User("mojo")));
        //orElseThrow,无元素则抛出异常
        //System.out.println(op2.orElseThrow(() -> new RuntimeException("mojo")));
        //map方法,调用function函数返回任意类型的Optional实例
        Optional<Integer> s = op1.map(u1 -> u1.getName().length());
        System.out.println("map方法" + s.get());
        //flatMap方法，调用者自己返回使用optional方法返回optional实例
        Optional<Integer> sa = op1.flatMap(u1 -> Optional.of(u1.getName().length()));
        //filter方法，按照自定义过滤规则过滤
        Optional<User> op3 = op1.filter(u1 -> u1.getName().length() > 2);
        List<User> users = new ArrayList<>();
        users.add(new User("tom"));
        users.add(new User("lily"));
        Optional<List<User>> ou1 = Optional.of(users);
        Optional<List<User>> ou2 = ou1.filter(l -> l.size() > 2);
        System.out.println(ou2.orElse(null));
        //==========实践==============
        Outer outer = new Outer();
        outer.nested = new Nested();
        outer.nested.inner = new Inner();

        if (outer != null && outer.nested != null && outer.nested.inner != null) {
            System.out.println(outer.nested.inner);
        }
        //map方法有值则返回正常结果的optional，否则返回空的optional
        Optional.of(outer).map(outer1 -> outer1.nested).map(nested -> nested.inner)
                .ifPresent(inner -> System.out.println(">>>" + inner));
        Optional<Inner> inner1 = Optional.ofNullable(outer).map(nested -> nested.nested).map(inner -> inner.inner);

    }
}

class Outer {
    String name;
    Nested nested;

}

class Nested {
    String name;
    Inner inner;
}

class Inner {

}